package org.chartsy.updatecenter; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.util.Observable; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.methods.GetMethod; /** * * @author Viorel */ public class Download extends Observable implements Runnable { private static final int MAX_BUFFER_SIZE = 1024; public static final String STATUSES[] = { "Downloading", "Paused", "Complete", "Cancelled", "Error" }; public static final int DOWNLOADING = 0; public static final int PAUSED = 1; public static final int COMPLETE = 2; public static final int CANCELLED = 3; public static final int ERROR = 4; private String url; private String folder; private int size; private int downloaded; private int status; public Download(String url) { this.url = url; folder = System.getProperty("user.home") + File.separator + "Chartsy" + File.separator + "downloads"; size = -1; downloaded = 0; status = DOWNLOADING; download(); } public String getUrl() { return url; } public int getSize() { return size; } public float getProgress() { return ((float) downloaded/size) * 100; } public int getStatus() { return status; } public void pause() { status = PAUSED; stateChanged(); } public void resume() { status = DOWNLOADING; stateChanged(); download(); } public void cancel() { status = CANCELLED; stateChanged(); } private void error() { status = ERROR; stateChanged(); } private void download() { Thread thread = new Thread(this); thread.start(); } public String getFilePath(String url) { return folder + File.separator + url.substring(url.lastIndexOf('/') + 1); } public String getFileName(String url) { return url.substring(url.lastIndexOf('/') + 1); } public void run() { RandomAccessFile file = null; InputStream stream = null; GetMethod method = null; try { HttpClient client = ProxyManager.manager().httpClient(); method = new GetMethod(url); method.setRequestHeader("Range", "bytes=" + downloaded + "-"); int responce = client.executeMethod(method); if (responce / 100 != 2) error(); Header header = method.getResponseHeader("Content-Length"); int contentLength = Integer.parseInt(header.getValue()); if (contentLength < 1) error(); if (size == -1) { size = contentLength; stateChanged(); } file = new RandomAccessFile(getFilePath(url), "rw"); file.seek(downloaded); stream = method.getResponseBodyAsStream(); while (status == DOWNLOADING) { byte buffer[]; if (size - downloaded > MAX_BUFFER_SIZE) buffer = new byte[MAX_BUFFER_SIZE]; else buffer = new byte[size - downloaded]; int read = stream.read(buffer); if (read == -1) break; file.write(buffer, 0, read); downloaded += read; stateChanged(); } if (status == DOWNLOADING) { status = COMPLETE; stateChanged(); } } catch (IOException ex) { error(); } finally { // Close file. if (file != null) { try { file.close(); } catch (Exception e) {} } // Close connection to server. if (stream != null) { try { stream.close(); } catch (Exception e) {} } if (method != null) { method.releaseConnection(); } } } private void stateChanged() { setChanged(); notifyObservers(); } }